<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2020/6/24 0024
 * Time: 17:16
 */
namespace app\currency\command;

use app\currency\service\CitiesService;
use app\currency\service\CleanerService;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\exception\DbException;
use think\exception\PDOException;

class AutoRun extends Command
{
    /**
     * 配置指令信息
     */
    protected function configure()
    {
        $this->setName('xclean:clean')->setDescription('[清理]检查并处理服务订单');
    }

    /**
     * 业务指令执行
     * @param Input $input
     * @param Output $output
     * @return int|void|null
     * @throws DataNotFoundException
     * @throws DbException
     * @throws Exception
     * @throws ModelNotFoundException
     * @throws PDOException
     */
    protected function execute(Input $input, Output $output)
    {
        // 自动取消30分钟未支付的订单
        $this->autoCancelOrder();
        // 清理一天前未支付的订单
        $this->autoRemoveOrder();
        // 自动结算
        $this->autoSettlement();
        // 订单自动退款处理
        // $this->autoRefundOrder();
        // 提现自动打款处理
        // $this->autoTransfer();
    }

    /**
     * 自动结算
     */
    private function autoSettlement()
    {
        $where = [['status', 'eq', '4'], ['settlement_status', 'eq', '0']];
        foreach (Db::name('CleanOrder')->where($where)->limit(10)->order('create_at asc')->select() as $order) {
            try {
                $this->output->writeln("正在为 {$order['order_no']} 执行结算操作...");
                $royalty_data = [];
                $address = CitiesService::getAddressText($order['cities_id'],'string');
                $bind_parent_ids = [];
                $agent_data = [];
                $cleaner_balance_log = [];
                if(Db::name('CitiesCleaner')->where([
                    ['cities_id','eq',$order['cities_id']],
                    ['cid','eq',$order['cid']]
                ])->count() > 0)
                {
                    //自己做自己绑定的订单，则不产生提成，所有收益自己一个人得
                    $royalty_data[] = [
                        'cid' => $order['cid'],
                        'ccid' => $order['cid'],
                        'mid' => $order['mid'],
                        'modal' => 'service',
                        'order_no' => $order['order_no'],
                        'order_price' => $order['total_price'],
                        'cities_id' => $order['cities_id'],
                        'address' => $address,
                        'amount' => $order['total_price']
                    ];
                    $service_parent_ids = [['id' => $order['cid'],'price' => $order['total_price']]];
                    $cleaner_balance_log[] = [
                        'cid' => $order['cid'],
                        'amount' => $order['total_price'],
                        'content' => "订单{$order['order_no']}【自己的】完结，您获得全额分成{$order['total_price']}元"
                    ];
                } else {

                    $total_price = $order['total_price'];
                    //绑定返利
                    $CleanerSaleRatio = sysconf('cleaner_sale_ratio');
                    $DirectInvitationSaleRatio = sysconf('direct_invitation_sale_ratio');
                    $IndirectInvitationSaleRatio = sysconf('indirect_invitation_sale_ratio');
                    $CleanerSalePrice = floor($CleanerSaleRatio * $total_price*100)/100;
                    $DirectInvitationSalePrice = floor($DirectInvitationSaleRatio * $total_price * 100)/100;
                    $IndirectInvitationSalePrice = floor($IndirectInvitationSaleRatio * $total_price * 100)/100;
                    //查询绑定用户
                    $citiesCleaner = Db::name('CitiesCleaner')->where('cities_id','eq',$order['cities_id'])->field('cid')->find();
                    $bind_agent = 0;
                    if(!empty($citiesCleaner))
                    {
                        $bind_agent = CleanerService::getAgent($citiesCleaner['cid']);
                        $bind_parent_ids = CleanerService::getParentIds($citiesCleaner['cid'],2);
                        $bind_parent_ids[] = ['id' => $citiesCleaner['cid'],'lvl' => 0];
                    }
                    foreach ($bind_parent_ids as &$bind_parent) {
                        $bind_desc = '未知';
                        switch ($bind_parent['lvl'])
                        {
                            case 0:
                                $bind_parent['price'] = $CleanerSalePrice;
                                $bind_desc = '自己绑定的';
                                break;
                            case 1:
                                $bind_parent['price'] = $DirectInvitationSalePrice;
                                $bind_desc = '直属团队绑定';
                                break;
                            case 2:
                                $bind_parent['price'] = $IndirectInvitationSalePrice;
                                $bind_desc = '间接团队绑定';
                        }
                        if($bind_parent['price'] > 0)
                        {
                            $royalty_data[] = [
                                'cid' => $bind_parent['id'],
                                'ccid' => $citiesCleaner['cid'],
                                'mid' => $order['mid'],
                                'modal' => 'bind',
                                'order_no' => $order['order_no'],
                                'order_price' => $order['total_price'],
                                'cities_id' => $order['cities_id'],
                                'address' => $address,
                                'amount' => $bind_parent['price']
                            ];
                            $cleaner_balance_log[] = [
                                'cid' => $bind_parent['id'],
                                'amount' => $bind_parent['price'],
                                'content' => "订单{$order['order_no']}【{$bind_desc}】完结，您获得销售分成{$bind_parent['price']}元"
                            ];
                        }
                    }
                    //服务返利
                    $CleanerWorkRatio = sysconf('cleaner_work_ratio');
                    $DirectInvitationWorkRatio = sysconf('direct_invitation_work_ratio');
                    $IndirectInvitationWorkRatio = sysconf('indirect_invitation_work_ratio');
                    $CleanerWorkPrice = floor($CleanerWorkRatio * $total_price * 100)/100;
                    $DirectInvitationWorkPrice = floor($DirectInvitationWorkRatio * $total_price *100)/100;
                    $IndirectInvitationWorkPrice = floor($IndirectInvitationWorkRatio * $total_price * 100)/100;
                    //查询服务上级
                    $service_parent_ids = CleanerService::getParentIds($order['cid'],2);
                    $service_parent_ids[] = ['id' => $order['cid'],'lvl' => 0];
                    foreach ($service_parent_ids as &$service_parent) {
                        $service_desc = "未知";
                        switch ($service_parent['lvl'])
                        {
                            case 0:
                                $service_parent['price'] = $CleanerWorkPrice;
                                $service_desc = "自己做的";
                                break;
                            case 1:
                                $service_parent['price'] = $DirectInvitationWorkPrice;
                                $service_desc = "直属团队做的";
                                break;
                            case 2:
                                $service_parent['price'] = $IndirectInvitationWorkPrice;
                                $service_desc = "间接团队做的";
                        }
                        if($service_parent['price'] > 0)
                        {
                            $royalty_data[] = [
                                'cid' => $service_parent['id'],
                                'ccid' => $order['cid'],
                                'mid' => $order['mid'],
                                'modal' => 'service',
                                'order_no' => $order['order_no'],
                                'order_price' => $order['total_price'],
                                'cities_id' => $order['cities_id'],
                                'address' => $address,
                                'amount' => $service_parent['price']
                            ];
                            $cleaner_balance_log[] = [
                                'cid' => $service_parent['id'],
                                'amount' => $service_parent['price'],
                                'content' => "订单{$order['order_no']}【{$service_desc}】完结，您获得做工分成{$service_parent['price']}元"
                            ];
                        }

                    }
                    //代理商返利
                    $agent_data = [];
                    $service_agent = CleanerService::getAgent($order['cid']);
                    if(!empty($service_agent))
                    {
                        $agent_service_ratio = sysconf('agent_service_ratio');
                        $agent_service_price = floor($agent_service_ratio * $total_price * 100)/100;
                        if($agent_service_price > 0)
                        {
                            $agent_data[] = [
                                'agent_id' => $service_agent,
                                'cid' => $order['cid'],
                                'modal' => 'service',
                                'mid' => $order['mid'],
                                'order_no' => $order['order_no'],
                                'order_price' => $order['total_price'],
                                'cities_id' => $order['cities_id'],
                                'address' => $address,
                                'amount' => $agent_service_price
                            ];
                        }

                    }
                    if(!empty($bind_agent)){
                        $agent_sale_ratio = sysconf('agent_sale_ratio');
                        $agent_sale_price = floor($agent_sale_ratio * $total_price * 100)/100;
                        if($agent_sale_price > 0)
                        {
                            $agent_data[] = [
                                'agent_id' => $bind_agent,
                                'cid' => $citiesCleaner['cid'],
                                'modal' => 'bind',
                                'mid' => $order['mid'],
                                'order_no' => $order['order_no'],
                                'order_price' => $order['total_price'],
                                'cities_id' => $order['cities_id'],
                                'address' => $address,
                                'amount' => $agent_sale_price
                            ];
                        }
                    }
//                    if($bind_agent > 0)
//                    {
//                        $agent_bind_price = $total_price;
//                        $agent_bind_price -= $CleanerSalePrice;
//                        $agent_bind_price -= $DirectInvitationSalePrice;
//                        $agent_bind_price -= $IndirectInvitationSalePrice;
//                        $agent_bind_price -= $CleanerWorkPrice;
//                        $agent_bind_price -= $DirectInvitationWorkPrice;
//                        $agent_bind_price -= $IndirectInvitationWorkPrice;
//                        $agent_bind_price -= $agent_service_price;
//                        if($agent_bind_price > 0)
//                        {
//                            $agent_data[] = [
//                                'agent_id' => $service_agent,
//                                'cid' => $order['cid'],
//                                'modal' => 'bind',
//                                'mid' => $order['mid'],
//                                'order_no' => $order['order_no'],
//                                'order_price' => $order['total_price'],
//                                'cities_id' => $order['cities_id'],
//                                'address' => $address,
//                                'amount' => $agent_service_price
//                            ];
//                        }
//
//                    }
                }
                Db::transaction(function() use($order,$royalty_data,$bind_parent_ids,$service_parent_ids,$agent_data,$cleaner_balance_log){
                    //修改订单状态
                    Db::name('CleanOrder')->where(['order_no' => $order['order_no']])->update([
                        'settlement_status' => '1',  'settlement_at' => date('Y-m-d H:i:s')
                    ]);
                    //插入返利记录
                    if(!empty($royalty_data))
                    {
                        Db::name('CleanOrderRoyalty')->insertAll($royalty_data);
                    }
                    //增加余额
                    foreach ($bind_parent_ids as $bind_parent_id) {
                        if($bind_parent_id['price'] > 0){
                            Db::name('Cleaner')
                                ->where('id','eq',$bind_parent_id['id'])
                                ->setInc('balance',$bind_parent_id['price']);
                        }
                    }
                    foreach ($service_parent_ids as $service_parent_id) {
                        if($service_parent_id['price'] > 0)
                        {
                            Db::name('Cleaner')
                                ->where('id','eq',$service_parent_id['id'])
                                ->setInc('balance',$service_parent_id['price']);
                        }

                    }
                    //余额记录
                    if(!empty($cleaner_balance_log))
                    {
                        Db::name('CleanerBalanceLog')->insertAll($cleaner_balance_log);
                        //todo::插入模板消息
                    }
                    //代理商返利记录
                    if(!empty($agent_data))
                    {
                        Db::name('AgentRebate')->insertAll($agent_data);
                        foreach ($agent_data as $agent_datum) {
                            Db::name('Agent')->where('id',$agent_datum['agent_id'])->setInc('balance',$agent_datum['amount']);
                        }
                    }
                });
            } catch (\Exception $e) {
                $msg = 'Error: ' . $e->getMessage(); // 获取错误信息
                $msg .= $e->getTraceAsString();
                $msg .= '异常行号：' . $e->getLine();
                $msg .= '所在文件：' . $e->getFile();
                $this->output->writeln("订单 {$order['order_no']} 执行结算失败，{$msg}！");
            }
        }
        $this->output->writeln('自动检测结算订单执行完成！');
    }
    /**
     * 自动取消30分钟未支付的订单
     * @throws Exception
     * @throws PDOException
     */
    private function autoCancelOrder(){
        $datetime = $this->getDatetime('service_order_wait_time');
        $where = [['status', 'eq', '1'], ['create_at', '<', $datetime]];
        $count = Db::name('CleanOrder')->where($where)->update([
            'status'       => '0'
        ]);
        if ($count > 0) {
            $this->output->info("共计自动取消了30分钟未接单的{$count}笔订单！");
        } else {
            $this->output->comment('没有需要自动取消30分钟未接单的订单记录！');
        }
    }

    /**
     * 清理一天前未支付的订单
     * @throws Exception
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws PDOException
     */
    private function autoRemoveOrder(){
        $datetime = $this->getDatetime('service_order_clear_time');
        $where = [['status', 'eq', '0'], ['create_at', '<', $datetime]];
        $list = Db::name('CleanOrder')->where($where)->limit(20)->select();
        if (count($orderNos = array_unique(array_column($list, 'order_no'))) > 0) {
            $this->output->info("自动删除前一天已经取消的订单：" . PHP_EOL . join(',' . PHP_EOL, $orderNos));
            Db::name('CleanOrder')->whereIn('order_no', $orderNos)->delete();
        } else {
            $this->output->comment('没有需要自动删除前一天已经取消的订单！');
        }
    }

    /**
     * 获取配置时间
     * @param string $code
     * @return string
     * @throws Exception
     * @throws PDOException
     */
    private function getDatetime($code)
    {
        $minutes = intval(sysconf($code) * 60);
        return date('Y-m-d H:i:s', strtotime("-{$minutes} minutes"));
    }
}